package com.motong.gongdan.config.mqtt;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.motong.gongdan.entity.DeviceInfo;
import com.motong.gongdan.service.DeviceInfoService;
import com.motong.gongdan.service.ExceptionInfoService;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.vo.system.device.vo.DeviceDataVo;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Objects;

import static com.motong.gongdan.constant.CommonConstant.REDIS_KEY_PREFIX;

@Slf4j
@Configuration
public class MqttProviderCallBack implements MqttCallback {

    private static RedisTemplate<String, Object> redisTemplate;

    @Resource
    @Qualifier("redisTemplate")
    private RedisTemplate<String, Object> redisTemplateOri;

    private static DeviceInfoService deviceInfoService;
    @Resource
    private DeviceInfoService deviceInfoServiceOri;

    private static ExceptionInfoService exceptionInfoService;
    @Resource
    private ExceptionInfoService exceptionInfoServiceOri;

    @Value("${mqtt.client.id}")
    private String clientId;

    @PostConstruct
    public void init() {
        MqttProviderCallBack.redisTemplate = this.redisTemplateOri;
        MqttProviderCallBack.deviceInfoService = this.deviceInfoServiceOri;
        MqttProviderCallBack.exceptionInfoService = this.exceptionInfoServiceOri;
    }


    @Override
    public void connectionLost(Throwable cause) {
        System.out.println(clientId + "与服务器断开连接。" + cause.getMessage());
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) {
        try {
            int lastIndexOf = topic.lastIndexOf("/");
            String messageContent = new String(message.getPayload());
            String deviceSn;
            if (topic.startsWith("topic/sys/device") || lastIndexOf < 0) {
                return;
            }
            /*---------------------------------------------*/
            deviceSn = topic.substring(lastIndexOf + 1);
            JSONObject jsonContent = JSONUtil.parseObj(messageContent);
            // 非本家设备处理
            LoginUtil.setIgnoreFactory(true);
            DeviceDataVo data = deviceInfoService.getAvailableData(deviceSn, jsonContent);
            if (Objects.isNull(data) || data.checkIsAllNull()) {
                log.error("数据一致无需处理");
                return;
            }
            DeviceInfo deviceInfo = data.getDeviceInfo();
            if (Objects.nonNull(deviceInfo)) {
                LoginUtil.setIgnoreFactory(false);
                LoginUtil.setLoginUserFactory(deviceInfo.getFactoryId());
            }
            if (Objects.nonNull(data.getDeviceStatus())) {
                deviceInfoService.changeStatus(data);
            }
            if (Objects.nonNull(data.getLampBStatus())) {
                if ("2".equals(data.getLampBStatus())) {
                    deviceInfoService.senDefaultLampRequest(data);
                }
                redisTemplate.opsForHash().put(REDIS_KEY_PREFIX.concat("device:lampBStatus"), deviceSn, data.getLampBStatus());
            }
            if (Objects.nonNull(data.getDeviceCount())) {
                deviceInfoService.changeCount(data);
                redisTemplate.opsForHash().put(REDIS_KEY_PREFIX.concat("device:count"), deviceSn, data.getDeviceCount());
            }
            if (Objects.nonNull(data.getCause()) && !"0".equals(data.getCause())) {
                exceptionInfoService.deviceDealException(data);
            }
            LoginUtil.setIgnoreFactory(false);
            /*---------------------------------------------*/
        } catch (Exception e) {
            log.error("发生异常topic{}", topic);
            log.error("发生异常message{}", message);
            e.printStackTrace();
        }
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        IMqttAsyncClient client = token.getClient();
        System.out.println(client.getClientId() + "发布消息成功！");
    }
}
